<template>
  <el-dialog
    v-model="dialogFormVisible"
    :title="title"
    width="80%"
    @close="close"
  >
    <el-form
      ref="formRef"
      v-loading="loading"
      :model="form"
      :rules="rules"
      label-width="80px"
    >
      <el-form-item label="角色名称" prop="name">
        <el-input v-model="form.name" />
      </el-form-item>
      <el-form-item label="菜单名">
        <div class="vab-tree-border">
          <!--<el-tree ref="treeData" :data="list" :default-expand-all="false" :props="defaultPermission" node-key="id"-->
          <!--         show-checkbox @check="handleCheck">-->
          <!--  <template #default="{ data }">-->
          <!--    <span>{{ data.name }}</span>-->
          <!--  </template>-->
          <!--</el-tree>-->
          <el-table
            ref="multipleTableRef"
            :data="list"
            :tree-props="{ children: 'children' }"
            border
            default-expand-all
            row-key="id"
            style="width: 100%"
            @select="handleSelection"
            @selection-change="handleSelectionChange"
            @select-all="handleSelectAll"
          >
            <el-table-column
              :reserve-selection="true"
              type="selection"
              width="55"
            />
            <el-table-column label="菜单" prop="name" width="280" />
            <el-table-column label="功能按钮">
              <template #default="{ row }">
                <el-checkbox-group
                  v-model="form.button_permission_ids"
                  @change="handleCheckBox($event, row)"
                >
                  <el-checkbox
                    v-for="item in row.button"
                    :key="item.id"
                    :label="item.id"
                  >
                    {{ item.name }}
                  </el-checkbox>
                </el-checkbox-group>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </el-form-item>
    </el-form>
    <template #footer>
      <el-button @click="close">取 消</el-button>
      <el-button type="primary" @click="save">确 定</el-button>
    </template>
  </el-dialog>
</template>

<script>
  import { doEdit, doAdd, getDetail } from '@/api/role'
  import { getList } from '@/api/permission'

  export default defineComponent({
    name: 'AdminRoleEdit',
    emits: ['fetch-data'],
    setup(props, { emit }) {
      const $baseMessage = inject('$baseMessage')
      const state = reactive({
        treeData: null,
        formRef: null,
        loading: false,
        form: {
          name: '',
          permission_ids: [],
          button_permission_ids: [],
        },
        rules: {},
        title: '',
        dialogFormVisible: false,
        list: [],
        multipleSelection: [],
        defaultPermission: {
          children: 'children',
          label: 'name',
        },
        multipleTableRef: null,
      })

      const showEdit = async (row) => {
        state.dialogFormVisible = true
        state.loading = true
        await fetchData()
        nextTick(async () => {
          if (!row) {
            state.title = '添加'
          } else {
            state.title = '编辑'
            const params = {
              id: row.id,
            }

            const { data } = await getDetail(params)
            state.form.id = row.id
            state.form.name = JSON.parse(JSON.stringify(row)).name
            state.form.button_permission_ids = data.button_permission_id
            state.form.permission_ids = data.permission_id
            recursionFuc(state.list, state.form.permission_ids)
            console.log('state.form.permission_id', state.form)
          }
          state.loading = false
        })
      }

      //递归函数
      const recursionFuc = (list, ids) => {
        console.log('123', list, ids)
        for (const item of list) {
          const Boole = _.includes(ids, item.id)
          console.log('Boole2', Boole)
          if (Boole) {
            console.log('item', item)
            state.multipleTableRef.toggleRowSelection(item, true)
          } else {
            state.multipleTableRef.toggleRowSelection(item, false)
          }
          if (!_.isEmpty(item.children)) {
            recursionFuc(item.children, ids)
          }
        }
      }

      const close = () => {
        state['formRef'].resetFields()
        // state.treeData.setCheckedKeys([]);
        state.form = {
          name: '',
          permission_ids: [],
          button_permission_ids: [],
        }
        state.multipleTableRef.clearSelection()
        state.dialogFormVisible = false
      }
      const fetchData = async () => {
        const { data } = await getList({ is_role: true })
        state.list = data
      }

      const handleSelectionChange = (val) => {
        const multipleSelection = JSON.parse(
          JSON.stringify(state.multipleSelection)
        )
        console.log('multipleSelection', multipleSelection, val)
        const differenceArr = _.differenceWith(
          multipleSelection,
          val,
          _.isEqual
        )
        console.log('differenceArr', differenceArr)

        if (!_.isEmpty(differenceArr) && !_.isEmpty(differenceArr[0].button)) {
          const idArr = []
          for (const item of differenceArr[0].button) {
            idArr.push(item.id)
          }
          state.form.button_permission_ids = _.difference(
            state.form.button_permission_ids,
            idArr
          )
          console.log(
            'state.form.button_permission_ids ',
            state.form.button_permission_ids
          )
        }

        state.multipleSelection = val
        console.log('list1', state.list, state.multipleSelection)
      }
      const handleSelectAll = (value) => {
        console.log('handleSelectAll', value)
        // 判断是全选还是全不选
        const isSelectAll = value.length > 0

        // 处理所有菜单项的选择状态和按钮权限
        processSelectAll(state.list, isSelectAll)
      }

      // 递归处理全选/全不选的菜单项及其按钮权限
      const processSelectAll = (list, isSelectAll) => {
        if (!list || list.length === 0) return

        list.forEach((item) => {
          // 设置菜单项的选择状态
          state.multipleTableRef.toggleRowSelection(item, isSelectAll)

          // 处理按钮权限
          if (item.button && item.button.length > 0) {
            if (isSelectAll) {
              // 全选时添加所有按钮权限
              item.button.forEach((btn) => {
                if (!state.form.button_permission_ids.includes(btn.id)) {
                  state.form.button_permission_ids.push(btn.id)
                }
              })
            } else {
              // 全不选时移除所有按钮权限
              state.form.button_permission_ids =
                state.form.button_permission_ids.filter(
                  (id) => !item.button.some((btn) => btn.id === id)
                )
            }
          }

          // 递归处理子菜单
          if (item.children && item.children.length > 0) {
            processSelectAll(item.children, isSelectAll)
          }
        })
      }

      const handleCheckBox = (value, row) => {
        console.log('list2', value, row)
        state.multipleTableRef.toggleRowSelection(row, true)
        nextTick(() => {
          findParent(state.list, row)
        })
        console.log('list2', value, state.multipleSelection)
      }

      const handleSelection = (value, row) => {
        console.log('handleSelection_value', value, row)
        const isSelected = value.some((item) => item.id === row.id)
        // 处理当前行的按钮
        if (row.button && row.button.length > 0) {
          if (isSelected) {
            // 选中行时，添加所有按钮
            row.button.forEach((btn) => {
              if (!state.form.button_permission_ids.includes(btn.id)) {
                state.form.button_permission_ids.push(btn.id)
              }
            })
          }
        }
        // 处理子菜单
        if (row.children && row.children.length > 0) {
          // 如果选中父菜单，递归选中所有子菜单
          if (isSelected) {
            row.children.forEach((child) => {
              state.multipleTableRef.toggleRowSelection(child, true)
              if (child.button && child.button.length > 0) {
                child.button.forEach((btn) => {
                  if (!state.form.button_permission_ids.includes(btn.id)) {
                    state.form.button_permission_ids.push(btn.id)
                  }
                })
              }
            })
          }
          // 如果取消选中父菜单，递归取消选中所有子菜单
          else {
            row.children.forEach((child) => {
              state.multipleTableRef.toggleRowSelection(child, false)
              if (child.button && child.button.length > 0) {
                state.form.button_permission_ids =
                  state.form.button_permission_ids.filter(
                    (id) => !child.button.some((btn) => btn.id === id)
                  )
              }

              // 递归处理更深层次的子菜单
              if (child.children && child.children.length > 0) {
                removeChildrenButtons(child.children)
              }
            })
          }
        }
        nextTick(() => {
          findParent(state.list, row)
        })
      }

      // 递归移除子菜单的所有按钮
      const removeChildrenButtons = (children) => {
        children.forEach((child) => {
          if (child.button && child.button.length > 0) {
            state.form.button_permission_ids =
              state.form.button_permission_ids.filter(
                (id) => !child.button.some((btn) => btn.id === id)
              )
          }

          if (child.children && child.children.length > 0) {
            removeChildrenButtons(child.children)
          }
        })
      }

      //找父节点
      const findParent = (list, row) => {
        const pid = [row.pid]
        console.log('pid', pid)
        for (const item of list) {
          const Boole = _.includes(pid, item.id)
          console.log('Boole2', Boole)
          if (Boole) {
            // state.multipleTableRef.toggleRowSelection(item, true)
            console.log('item', item)
            const intersection = _.intersectionWith(
              state.multipleSelection,
              item.children
            )
            console.log('intersection', intersection)

            if (!_.isEmpty(intersection)) {
              //找出是否还有其他children未选中的
              const difference = _.differenceWith(item.children, intersection)
              console.log('difference', difference)
              if (_.isEmpty(difference)) {
                //如果没有其他未选中的，则把当前父级设置为勾选状态(因框架问题，如果直接设置父级勾选，会有全部选中的情况，所以只能判断他的子级都有勾选了，才勾选父级)
                state.multipleTableRef.toggleRowSelection(item, true)
              }
            } else {
              const idArr = []
              _.forEach(row.children, function (value) {
                console.log(value)
                _.forEach(value.button, function (values) {
                  console.log(values)
                  idArr.push(values.id)
                })
              })
              state.form.button_permission_ids = _.difference(
                state.form.button_permission_ids,
                idArr
              )
            }
          }
          if (!_.isEmpty(item.children)) {
            findParent(item.children, row)
          }
        }
      }

      const save = () => {
        state['formRef'].validate(async (valid) => {
          if (valid) {
            // permission_ids
            // state.multipleSelection

            const multipleSelection = state.multipleSelection
            let permission_ids = []

            for (const item of multipleSelection) {
              permission_ids.push(item.id)
            }
            permission_ids = permission_ids.concat(
              state.form.button_permission_ids
            )
            permission_ids = _.compact(permission_ids)
            state.form.permission_ids = permission_ids
            console.log('permission_ids', permission_ids)
            if (state.form.id) {
              const { msg } = await doEdit(state.form)
              $baseMessage(msg, 'success', 'vab-hey-message-success')
            } else {
              const { msg } = await doAdd(state.form)
              $baseMessage(msg, 'success', 'vab-hey-message-success')
            }

            emit('fetch-data')
            close()
          }
        })
      }

      return {
        ...toRefs(state),
        handleSelectionChange,
        handleSelection,
        handleSelectAll,
        handleCheckBox,
        showEdit,
        recursionFuc,
        processSelectAll,
        close,
        fetchData,
        save,
      }
    },
  })
</script>

<style lang="scss" scoped>
  .vab-tree-border {
    width: 100%;
    height: 400px;
    overflow-y: auto;
    border: 1px solid #dcdfe6;
    border-radius: $base-border-radius;
  }
</style>
